/*
PearReview - The peer review assistant.
Copyright (C) 2009  Dimitrij Pankratz, Anton Musichin
http://www.pearreview.com, info@pearreview.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package com.pearreview.ui;

import javax.swing.*;
import javax.swing.plaf.basic.BasicButtonUI;

import com.pearreview.application.Messages;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;

/**
 * 
 * @author Dimitrij Pankratz, Anton Musichin
 * @version 1.1
 *
 */
public class CloseButtonTabComponent extends JPanel {

	private static final long serialVersionUID = -754937854640744235L;
	
	private JButton button;

	/**
	 * Class constructor.
	 * 
	 * @param pane
	 */
	public CloseButtonTabComponent(final JTabbedPane pane) {
		super(new FlowLayout(FlowLayout.LEFT, 0, 0));
		
		if (pane == null) {
			throw new NullPointerException("Given JTabbedPane is null");
		}
		setOpaque(false);
		
		//Old HTML method to underline the tab text on focus
		/*
		//make JLabel read titles from JTabbedPane
		final JLabel label = new ShadowLabel("<html></html>") {
			
			private static final long serialVersionUID = -6227944502988185424L;
			@Override
			public String getText() {
				int i = pane.indexOfTabComponent(CloseButtonTabComponent.this);
				if (i >= 0) {
					String title = pane.getTitleAt(i);
					if(pane.hasFocus() && pane.getSelectedIndex() == i) {
						/* this tab has focus 
						title = "<u>" + title + "</u>";
					}
					super.setText("<html>" + title + "</html>");
					return super.getText();
				}
				return "<html></html>";
			}
			*/
			
		//TODO clean code and underline function
			//make JLabel read titles from JTabbedPane
			final JLabel label = new ShadowLabel("", new Color(0xaeaeae)) {
				
				private static final long serialVersionUID = -6227944502988185424L;
				@Override
				public String getText() {
					int i = pane.indexOfTabComponent(CloseButtonTabComponent.this);
					if (i >= 0) {
						String title = pane.getTitleAt(i);
						if(pane.hasFocus() && pane.getSelectedIndex() == i) {
							/* this tab has focus */
							this.setFocused(true);
						} else {
							this.setFocused(false);
						}
						if(pane.getSelectedIndex() == i) {
							this.setShadowColor(Color.WHITE);
						} else {
							this.setShadowColor(new Color(0xaeaeae));
						}
						super.setText(title);
						return super.getText();
					}
					return "";
				}
			@Override
			public void setText(String text) {
				// not allowed
			}
			@Override
			public Icon getIcon() {
				int i = pane.indexOfTabComponent(CloseButtonTabComponent.this);
				if (i >= 0) {
					super.setIcon(pane.getIconAt(i));
					return super.getIcon();
				}
				return null;
			}
			@Override
			public void setIcon(Icon icon) {
				// not allowed
			}
			@Override
			public String getToolTipText() {
				int i = pane.indexOfTabComponent(CloseButtonTabComponent.this);
				if (i >= 0) {
					super.setToolTipText(pane.getToolTipTextAt(i));
					return super.getToolTipText();
				}
				return null;
			}
			@Override
			public void setToolTipText(String text) {
				// not allowed
			}
		};
		
		add(label);
		//add more space between the label and the button
		label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
		
		//tab button
		button = new TabButton();
		add(button);
		//add more space to the top of the component
		setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
	}
	
	/**
	 * Adds an ActionListener to the close-button. 
	 * @param al
	 */
	public void addActionListener(ActionListener al) {
		button.addActionListener(al);
	}
	
	/**
	 * Removes an ActionListener from the close-button. 
	 * If the listener is the currently set Action for the button, 
	 * then the Action is set to null. 
	 * @param al
	 */
	public void removeActionListener(ActionListener al) {
		button.removeActionListener(al);
	}
	
	/**
	 * Returns an array of all the ActionListeners added to 
	 * close-button with addActionListener().
	 * @return all of the ActionListeners added or an empty array
	 *  if no listeners have been added
	 */
	public ActionListener[] getActionListener() {
		return button.getActionListeners();
	}

	/**
	 * A button used in tabs for closing the parent tab.
	 * 
	 * @author Dimitrij Pankratz, Anton Musichin
	 * @version 1.0
	 */
	private class TabButton extends JButton {
		/**
		 * 
		 */
		private static final long serialVersionUID = 8883014549927650894L;

		/**
		 * Class constructor.
		 */
		public TabButton() {
			int size = 17;
			setPreferredSize(new Dimension(size, size));
			setToolTipText(Messages.getString("PearReview.tabs.close_tab"));
			//Make the button looks the same for all Laf's
			setUI(new BasicButtonUI());
			//Make it transparent
			setContentAreaFilled(false);
			//No need to be focusable
			setFocusable(false);
			setBorder(BorderFactory.createEtchedBorder());
			setBorderPainted(false);
			//Making nice roll-over effect
			//we use the same listener for all buttons
			//addMouseListener(buttonMouseListener);
			setRolloverEnabled(true);
		}

		protected void paintComponent(Graphics g) {
			super.paintComponent(g);
			Graphics2D g2d = (Graphics2D) g.create();
			g2d.setStroke(new BasicStroke(2));
			g2d.setColor(new Color(0x1e,0x1e,0x1e));
			
			Color GradientTop;
			Color GradientBottom;
			Color borderColor;
			Stroke borderStroke;
			
			int w = getWidth() - 4;
			int h = getHeight() - 4;
			
			int x = (getWidth() - h) / 2;
			int y = (getHeight() - w) / 2;
			int cornerRound = 6;
			
			if (!getModel().isRollover()) {
				
				GradientTop = new Color(0xae, 0xae, 0xae);
				GradientBottom = new Color(0x98, 0x98, 0x98);
				
				borderColor = new Color(0x66, 0x66, 0x66);
				borderStroke = new BasicStroke(1.0f);
			} else {
				
				GradientTop = new Color(0xe2, 0x1d, 0x26);
				GradientBottom = new Color(0xc1, 0x26, 0x2c);
				
				borderColor = new Color(0x66, 0x66, 0x66);
				borderStroke = new BasicStroke(1.0f);
			}
			
			// Enable anti-aliasing
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
			RenderingHints.VALUE_ANTIALIAS_ON);

			g2d.setColor(Color.BLACK);

			Paint paint = new GradientPaint(0, y, GradientTop, 0, y + h, 
					GradientBottom);
			
			g2d.setPaint(paint);
			g2d.fillRoundRect(x, y, w, h, (int) cornerRound, 
					(int) cornerRound);
			
			Shape buttonShape = new RoundRectangle2D.Double(x, y, w, h, 
					cornerRound, cornerRound);
			
			Shape clip = g.getClip();

			g2d.setClip(clip);
			g2d.setColor(borderColor);
			g2d.setStroke(borderStroke);
			g2d.draw(buttonShape);
			g2d.setColor(new Color(0xe7,0xe7,0xe7));
			
			int delta = 6;
			Stroke closeStroke = new BasicStroke(2.0f);
			g2d.setStroke(closeStroke);
			g2d.drawLine(delta, delta, getWidth() - delta, getHeight() -delta);
			g2d.drawLine(getWidth() - delta, delta, delta, getHeight() -delta);
			
			g2d.dispose();
		}
	}
}